package com.rran.study.chat.ops.service.impl;

import com.alibaba.fastjson.JSON;
import com.rran.study.chat.common.model.Response;
import com.rran.study.chat.common.utils.BeanCopyUtil;
import com.rran.study.chat.common.utils.FeignResultUtil;
import com.rran.study.chat.common.utils.RedisUtil;
import com.rran.study.chat.friend.dto.request.AcceptFriendDTO;
import com.rran.study.chat.friend.dto.request.AddFriendDTO;
import com.rran.study.chat.friend.dto.response.QueryFriendAppListVO;
import com.rran.study.chat.friend.dto.response.QueryFriendsListVO;
import com.rran.study.chat.ops.client.FriendClient;
import com.rran.study.chat.ops.enums.MessageType;
import com.rran.study.chat.ops.pojo.socketmsg.AcceptFriendMsg;
import com.rran.study.chat.ops.pojo.socketmsg.AddFriendMsg;
import com.rran.study.chat.ops.repository.ChannelFactory;
import com.rran.study.chat.ops.service.FriendService;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author yy
 * @Type FriendServiceImpl.java
 * @Desc
 * @date 2020/8/11 11:50
 */
@Service
@Slf4j
public class FriendServiceImpl implements FriendService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private FriendClient friendClient;

    @Autowired
    private FeignResultUtil feignResultUtil;

    @Override
    public Response<QueryFriendsListVO> queryFriendsList(String beanId) {
        Response<QueryFriendsListVO> result = friendClient.queryFriendsList(beanId);
        log.info("获取好友列表result <==={}", JSON.toJSONString(result));
        feignResultUtil.checkResultCode(result.getCode(), result.getDescription());
        return result;
    }

    @Override
    public Response addFriend(AddFriendDTO addFriendDTO) {
        //1.建立好友关系
        Response result = friendClient.addFriend(addFriendDTO);
        log.info("添加好友result <==={}", JSON.toJSONString(result));
        feignResultUtil.checkResultCode(result.getCode(), result.getDescription());
        if (result.getData() == null) {
            return Response.success();
        }
        //创建Msg对象
        AddFriendMsg addFriendMsg = new AddFriendMsg();
        BeanCopyUtil.copyFromSrcToDest(addFriendDTO, addFriendMsg);
        addFriendMsg.setId((Long) result.getData());
        addFriendMsg.setMessageType(MessageType.ADD_FRIEND);
        //websocket 推送
        String target = addFriendDTO.getTarget();
        ChannelHandlerContext ctx = ChannelFactory.getChannelHandlerContext(target);
        try {
            ctx.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(addFriendMsg)));
        } catch (NullPointerException e) {
            log.info(target + "用户下线了，发送失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Response.success();
    }

    @Override
    public Response acceptFriend(AcceptFriendDTO acceptFriendDTO) {
        //redis 1.先更新redis好友列表
        String sourceKey = acceptFriendDTO.getSource() + ":" + "friends";
        String targetKey = acceptFriendDTO.getTarget() + ":" + "friends";
        redisUtil.sAdd(sourceKey, acceptFriendDTO.getTarget());
        redisUtil.sAdd(targetKey, acceptFriendDTO.getSource());

        //2.修改好友申请记录状态
        Response<Integer> result = friendClient.acceptFriend(acceptFriendDTO);
        log.info("修改好友申请记录状态result <==={}", JSON.toJSONString(result));
        feignResultUtil.checkResultCode(result.getCode(), result.getDescription());
        if (result.getData() == 0) {
            return Response.success();
        }
        //3.webSocket 推送
        ChannelHandlerContext ctxTarget = ChannelFactory.getChannelHandlerContext(acceptFriendDTO.getTarget());
        ChannelHandlerContext ctxSource = ChannelFactory.getChannelHandlerContext(acceptFriendDTO.getSource());
        AcceptFriendMsg acceptFriendMsg = new AcceptFriendMsg();
        BeanCopyUtil.copyFromSrcToDest(acceptFriendDTO, acceptFriendMsg);
        acceptFriendMsg.setMessageType(MessageType.ACCEPT_FRIEND);
        try {
            ctxTarget.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(acceptFriendMsg)));
        } catch (NullPointerException e) {
            log.info(acceptFriendDTO.getTarget() + "用户下线了，发送失败");
        } catch (Exception e) {
            log.error("socket异常：{}",e.getMessage());
        }
        try {
            ctxSource.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(acceptFriendMsg)));
        } catch (NullPointerException e) {
            log.info(acceptFriendDTO.getSource() + "用户下线了，发送失败");
        } catch (Exception e) {
            log.error("socket异常：{}",e.getMessage());
        }
        return Response.success();
    }

    @Override
    public Response<List<QueryFriendAppListVO>> friendApplicationRecords(String beanId) {
        Response<List<QueryFriendAppListVO>> result = friendClient.friendApplicationRecords(beanId);
        log.info("获取好友申请列表result <==={}", JSON.toJSONString(result));
        feignResultUtil.checkResultCode(result.getCode(), result.getDescription());
        return result;
    }
}
